home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / gc / GCcheck_ptr.c < prev    next >
C/C++ Source or Header  |  1991-08-09  |  7KB  |  227 lines

  1. /* begincopyright
  2.   Copyright (c) 1988,1990 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.     
  15.   Parts of this software were derived from code bearing the copyright notice:
  16.   
  17.   Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
  18.   This material may be freely distributed, provided this notice is retained.
  19.   This material is provided as is, with no warranty expressed or implied.
  20.   Use at your own risk.
  21.   
  22.   endcopyright */
  23.   
  24. /* Check whether p points to a valid unmarked object.  Continue to the   */
  25. /* next iteration if not.  Set h to point to the beginning of the block  */
  26. /* containing p.  Set word_no to the offset of the beginning of the   */
  27. /* object.  Set sz to the size of the object in words.              */
  28. /* Set the bool variable is_atomic appropriately.              */
  29. /* Assumes surrounding declarations "long word_no; struct hblk *h".   */
  30. /* If SEPARATE_HEADERS is defined, we assume a surrounding decl          */
  31. /* "register struct hblkhdr * hhdr" and set hhdr to the header for    */
  32. /* the block containing p.                          */
  33. /* We continue to the next iteration by invoking the CONTINUE macro.  */
  34. /* If CONTINUE_M is defined, we use it when we find something         */
  35. /* that looks like a marked object.                      */
  36. /* This is an include file because it is used twice, and in at least  */
  37. /* one case we may not be able to afford the procedure calling        */
  38. /* overhead (except maybe on a SPARC).                     */
  39. /* Assumes that quicktest(p) holds.                      */
  40.  
  41. # ifndef CONTINUE_M
  42. #   define CONTINUE_M CONTINUE
  43. #   define DEFINED_CONTINUE_M
  44. # endif
  45.  
  46. {
  47. # ifdef RESTRICTED_INTERIOR_POINTERS
  48.     register unsigned long orig_p = (unsigned long)p;
  49. # endif
  50.   register char * map_ptr;
  51.   register int map_entry;
  52.  
  53.   /* if not a pointer to obj on heap, skip it */
  54.     if (((char *) p) >= GC_heaplim) {
  55.     CONTINUE;
  56.     }
  57.  
  58.     h = HBLKPTR(p);
  59.  
  60. # ifndef INTERIOR_POINTERS
  61.     /* Check mark bit first, since this test is much more likely to */
  62.     /* fail than later ones.                                        */
  63.     word_no = WORD_NO(p,h);
  64. #   ifdef SEPARATE_HEADERS
  65.       hhdr = HDR(h);
  66.       if (hhdr == (struct hblkhdr *)0) {
  67.           CONTINUE;
  68.       }
  69.       if (mark_bit_from_hdr(hhdr, word_no)) {
  70.       CONTINUE_M;
  71.       }
  72. #   else
  73.       if (mark_bit(h, word_no)) {
  74.     CONTINUE_M;
  75.       }
  76. #   endif
  77. # endif
  78.  
  79. # ifdef INTERIOR_POINTERS
  80.     if (!is_hblk(h)) {
  81.       char m = get_map(h);
  82.     
  83.       /* Skip over any continuation blocks: */
  84.     while (m > 0 && m < 0x7f) {
  85.         h -= m;
  86.         m = get_map(h);
  87.     }
  88.       if (m == HBLK_INVALID) {
  89. #         ifdef REPORT_FAILURE
  90.         GC_vprintf("-> Pointer to non-heap loc: %X\n", p);
  91. #         endif
  92.       CONTINUE;
  93.       }
  94.     }
  95. #   ifdef SEPARATE_HEADERS
  96.       hhdr = HDR(h);
  97. #   endif
  98.     /* Force p to point to a longword aligned entity */
  99.       p = (struct obj *)(((long)p) & ~(BYTES_PER_WORD - 1));
  100.     word_no = WORD_NO(p,h);
  101. #   if !defined(SEPARATE_HEADERS) || HDR_BYTES != 0
  102.       if (word_no < HDR_WORDS) {
  103.     CONTINUE;
  104.       }
  105. #   endif
  106. # else
  107.     if (!is_hblk(h)) {
  108. #    ifdef REPORT_FAILURE
  109.       GC_vprintf("-> Pointer to non-heap loc: %X\n", p);
  110. #       endif
  111.     CONTINUE;
  112.     }
  113. # endif
  114. # ifdef SEPARATE_HEADRERS
  115.     sz = hb_sz_from_hdr(hhdr);
  116. # else
  117.     sz = hb_sz(h);
  118. # endif
  119.  
  120.     if (sz < 0) {
  121.         sz = -sz;
  122.         is_atomic = TRUE;
  123.     } else {
  124.         is_atomic = FALSE;
  125.     }
  126.  
  127.     if (sz <= MAXOBJSZ) {
  128.       if ((map_ptr = obj_map[sz]) == (char *) 0) { 
  129. #    ifdef COUNT_CACHE_HITS
  130.       map_cache_misses++;
  131. #    endif
  132. #       ifdef INTERIOR_POINTERS
  133.           word_no = adjusted_word_no(word_no,sz);
  134. #       else
  135.           if (!is_proper_obj(word_no,sz)) {
  136. #           ifdef REPORT_FAILURE
  137.           GC_vprintf("-> Bad pointer to heap block: %X,sz = %d\n",p,sz);
  138. #        endif
  139.         CONTINUE;
  140.           }
  141. #      endif
  142.         if (word_no + sz > BYTES_TO_WORDS(HBLKSIZE)) {
  143.         /* 
  144.          * Note that we dont necessarily check for pointers to the block
  145.          * header. This doesn't cause any problems, since we have mark
  146.          * bits allocated for such bogus objects.
  147.          * We have to check for references past the last object, since
  148.          * marking from uch an "object" could cause an invalid memory
  149.          * reference.
  150.          */
  151. #         ifdef REPORT_FAILURE
  152.         GC_vprintf("-> Bad pointer to heap block: %X,sz = %d\n",p,sz);
  153. #      endif
  154.       CONTINUE;
  155.         }
  156.       } else /* we have a map of the block */ {
  157.         map_entry = map_ptr[word_no];
  158. #    ifdef COUNT_CACHE_HITS
  159.       map_cache_hits++;
  160. #    endif 
  161.         if (map_entry == OBJ_INVALID) {
  162. #         ifdef REPORT_FAILURE
  163.         GC_vprintf("-> Bad pointer to mapped heap block: %X,sz = %d\n",
  164.                    p,sz);
  165. #      endif
  166.       CONTINUE;
  167.         }
  168. #       ifdef INTERIOR_POINTERS
  169.           word_no -= map_entry;
  170. #       endif
  171.       }
  172.     } else /* large objects */ {
  173. #     ifdef INTERIOR_POINTERS
  174.     if (word_no >= HDR_WORDS + sz) {
  175. #           ifdef REPORT_FAILURE
  176.           GC_vprintf("-> Bad pointer to l.o. heap block: %X,sz = %d\n",
  177.                      p,sz);
  178. #        endif
  179.         CONTINUE;
  180.     }
  181.     word_no = HDR_WORDS;
  182. #     else
  183.         if (word_no != HDR_WORDS) {
  184. #         ifdef REPORT_FAILURE
  185.         GC_vprintf("-> Bad pointer to l.o. heap block: %X,sz = %d\n",p,sz);
  186. #      endif
  187.       CONTINUE;
  188.         }
  189. #     endif      
  190.     }
  191.  
  192.  
  193. #   ifdef INTERIOR_POINTERS
  194. #     ifdef SEPARATE_HEADERS
  195.         if (mark_bit_from_hdr(hhdr, word_no)) {
  196.       CONTINUE_M;
  197.         }
  198. #     else
  199.         if (mark_bit(h, word_no)) {
  200.       CONTINUE_M;
  201.         }
  202. #     endif
  203. #   endif
  204.  
  205. #   ifdef RESTRICTED_INTERIOR_POINTERS
  206.       /* Must still check that the offset is actually valid */
  207.         {
  208.           register long offset = ((char *)orig_p)
  209.                        - (((char *)h) + WORDS_TO_BYTES(word_no));
  210.       if (offset >= MAX_OFFSET || !valid_offsets[offset]) {
  211. #           ifdef REPORT_FAILURE
  212.           GC_vprintf(
  213.             "-> Bad offset into object %X,sz= %d, offset= %d\n",
  214.             orig_p,sz,offset);
  215. #        endif
  216.         CONTINUE;
  217.       }
  218.     }
  219. #   endif
  220.  
  221. }
  222.  
  223. # ifdef DEFINED_CONTINUE_M
  224. #   undef CONTINUE_M
  225. #   undef DEFINED_CONTINUE_M
  226. # endif
  227.